﻿using DearlerPlatform.Domain;
using DearlerPlatfrom.Core.Core;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace DearlerPlatfrom.Core.Repository
{
    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        private readonly DearlerPlarfromDbContext _context;

        public Repository(DearlerPlarfromDbContext context)
        {
            _context = context;
        }



        public async Task<List<TEntity>> GetListAsync(PageWithSortDto dto)
        {
            int skip = (dto.PageIndex - 1) * dto.PageSize;
            var dbset = _context.Set<TEntity>();
            return await dbset.Skip(skip).Take(dto.PageSize).ToListAsync();
        }
        public IQueryable<TEntity> GetQueryable(PageWithSortDto dto)
        {
            int skip = (dto.PageIndex - 1) * dto.PageSize;
            var dbset = _context.Set<TEntity>();
            return dbset.Skip(skip).Take(dto.PageSize);
        }


        public IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate)
        {
            var dbset = _context.Set<TEntity>();
            return dbset.Where(predicate);
        }


        public async Task<List<TEntity>> GetListAsync()
        {
            return await GetListAsync(new PageWithSortDto
            {
                Sort = "Id",
                PageIndex = 0,
                PageSize = 10,
                order = OrderType.Asc
            });
        }

        public async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, string orderBy, int pageIndex = 10, int pageSize = 1)
        {
            int skip = (pageIndex - 1) * pageSize;
            var dbset = _context.Set<TEntity>();
            //.OrderBy(o => o.GetType().GetProperty(orderBy).GetValue(o)).Skip(skip)
            return await dbset.Where(predicate).Skip(skip).Take(pageSize).ToListAsync();
        }
        public async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate)
        {
            var dbset = _context.Set<TEntity>();
            return await dbset.Where(predicate).ToListAsync();
        }


        public TEntity Get(Func<TEntity, bool> predicate)
        {
            return _context.Set<TEntity>().FirstOrDefault(predicate);
        }
        public async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await _context.Set<TEntity>().FirstOrDefaultAsync(predicate);
        }

        public TEntity Insert(TEntity entity)
        {
            var res = _context.Set<TEntity>().Add(entity).Entity;
            _context.SaveChanges();
            return res;
        }
        public async Task<TEntity> InsertAsync(TEntity entity)
        {
            var res = (await _context.Set<TEntity>().AddAsync(entity)).Entity;
            await _context.SaveChangesAsync();
            return res;
        }

        public TEntity Delete(TEntity entity)
        {
            var res = _context.Set<TEntity>().Remove(entity).Entity;
            _context.SaveChanges();
            return res;
        }
        public async Task<TEntity> DeleteAsync(TEntity entity)
        {
            var res = (_context.Set<TEntity>().Remove(entity)).Entity;
            await _context.SaveChangesAsync();
            return res;
        }

        public TEntity Update(TEntity entity)
        {
            var res = _context.Set<TEntity>().Update(entity).Entity;
            _context.SaveChanges();
            return res;
        }
        public async Task<TEntity> UpdateAsync(TEntity entity)
        {
            var res = (_context.Set<TEntity>().Update(entity)).Entity;
            await _context.SaveChangesAsync();
            return res;
        }


    }
}
